![pyannote.audioを使った話者ダイアライゼーションをオフラインで動かす方法](https://devio2023-media.developers.io/wp-content/uploads/2020/05/eyecatch_machine_learning.png)
pyannote.audioを使った話者ダイアライゼーションをオフラインで動かす方法
こんちには。
データアナリティクス事業本部 インテグレーション部 機械学習チームの中村です。
今回はpyannote.audioを使った話者ダイアライゼーションをオフラインで動かす方法を見ていこうと思います。
以下の記事のオフライン版となります。
こちらを以下の用途を目的としてオフラインモデルとして読み込めるように検討していきます
- ネットワーク的に閉じた環境でジョブを実行したい
- 推論時に毎回ダウンロードすることなしに高速に処理を開始できるようにしたい
pyannote.audioとは
pyannote.audioとは話者ダイアライゼーションを行うライブラリです。
GitHubは以下となります。
ベースのフレームワークはPyTorchとなっており、end-to-endの話者ダイアライゼーションを実現します。
話者ダイアライゼーションとは、どこの時間でどの話者がしゃべったのか、話者認識をせずに実施する技術のことを指します。
詳細は以下の過去のブログもご参照ください。
モデルの構成
pyannote.audioはHugging Faceで展開されているライブラリを複数使用してその処理を実現しています。
トップのモジュールはpyannote/speaker-diariation
で、依存モジュールとしてpyannote/segmentation
とspeechbrain/spkrec-ecapa-voxceleb
があるという構成となっています。
またpyannote/speaker-diariation
とpyannote/segmentation
は使用する場合にHugging Faceのトークンが必要で、普通に以下のようにトークンを指定して毎回ダウンロードが必要になります。
pipeline = Pipeline.from_pretrained( "pyannote/speaker-diarization@2.1" , use_auth_token="<Hugging Faceコンソールでの操作で取得したトークン>" )
こちらを以下の用途を目的としてオフラインモデルとして読み込めるように検討していきます。
オフライン化の方法
pyannote.audio側
pyannote/speaker-diariation
とpyannote/segmentation
についてはオフライン化の手順が以下のノートブックで言及されています。
このうちOffline useの節に方法の記載があります。
ただし説明例がpyannote/voice-actrivity-detection
となっている点はご注意ください。
pyannote.audio
自体に様々なライブラリがあるため、pyannote/voice-actrivity-detection
をpyannote/speaker-diarization
に読み替えます。
すなわち、今回の場合はpyannote/speaker-diarization
からconfig.yaml
をダウンロードし、
pyannote/segmentation
からpytorch_model.bin
をダウンロードします。
そして最初にダウンロードしたconfig.yaml
の以下のsegmentation
の部分がpytorch_model.bin
のパスを指すように修正します。
pipeline: name: pyannote.audio.pipelines.SpeakerDiarization params: clustering: AgglomerativeClustering embedding: speechbrain/spkrec-ecapa-voxceleb embedding_batch_size: 32 embedding_exclude_overlap: true segmentation: ./pytorch_model.bin segmentation_batch_size: 32 params: clustering: method: centroid min_cluster_size: 15 threshold: 0.7153814381597874 segmentation: min_duration_off: 0.5817029604921046 threshold: 0.4442333667381752
GitHubに記載されているのは、ここまででpyannote/voice-actrivity-detection
の場合はこの手順で問題無く動作します。
しかし、pyannote/speaker-diarization
の場合、それ以外の依存ライブラリとしてspeechbrain/spkrec-ecapa-voxceleb
があるため、こちらもオフラインで動作するよう対応が必要となります。
speechbrain側
speechbrain/spkrec-ecapa-voxceleb
は特にトークン等を必要としないパブリックなライブラリで、デフォルトではモデル使用時に以下のキャッシュディレクトリにモデルファイルが保存されます。
~/.cache/huggingface/hub
今回、このキャッシュディレクトリはHUGGINGFACE_HUB_CACHE
という環境変数を設定すれば変更が可能であることを利用し、キャッシュディレクトリの内容物をzipで固めて、ポータブルに扱えるようにしてみます。
やってみた
使用環境
Google Colaboratoryを使います。ハードウェアアクセラレータはGPU、GPUのタイプはT4、ラインタイム仕様は標準で実施します。
主なバージョン情報は以下です。
!python --version # Python 3.10.12
パッケージのバージョンは以下です。(こちらは準備を一通り実施した後に確認できます)
!pip freeze | grep \ -e "torch==" -e "torch" -e "speechbrain" -e "pyannote" \ -e "ipython==" -e "huggingface-hub" # huggingface-hub==0.17.3 # ipython==7.34.0 # pyannote.audio==2.1.1 # pyannote.core==4.5 # pyannote.database==4.1.3 # pyannote.metrics==3.2.1 # pyannote.pipeline==2.3 # pytorch-lightning==1.6.5 # pytorch-metric-learning==1.7.3 # speechbrain==0.5.12 # torch==1.11.0 # torch-audiomentations==0.11.0 # torch-pitch-shift==1.2.4 # torchaudio==0.11.0 # torchdata==0.6.1 # torchmetrics==0.11.4 # torchsummary==1.5.1 # torchtext==0.12.0 # torchvision==0.12.0
Hugging Faceコンソールでの操作
最初のダウンロードにはHugging Faceでの操作が必要ですので、まずはHugging Faceのアカウントを作成してログインします。
その後、以下2つのリポジトリのuser condition
をAccept
する必要があります。
Accept画面は以下のように表示されるので、必要事項を入力してボタンを押下してください。
その後、ユーザ管理画面の以下のURLにアクセスし、トークンを作成しておきます。
環境設定
pyannote.audioに関するインストールをします。
# for speechbrain !pip install -qq torch==1.11.0 torchvision==0.12.0 torchaudio==0.11.0 torchtext==0.12.0 !pip install -qq speechbrain==0.5.12 # pyannote.audio !pip install -qq pyannote.audio==2.1.1 # for visualization purposes !pip install -qq ipython==7.34.0
モデル取得
まずは以下でキャッシュフォルダを変更しておきます。
import os os.environ['HUGGINGFACE_HUB_CACHE'] = './assets' # デフォルト(未指定)の場合は ~/.cache/huggingface/hub
その後、以下でHugging Faceからモデルを取得します。
HF_TOKEN = "{作成したHugging Faceのトークン}" from huggingface_hub import hf_hub_download, snapshot_download config_path = hf_hub_download(repo_id="pyannote/speaker-diarization", filename="config.yaml", use_auth_token=HF_TOKEN) segmentation_model_path = hf_hub_download(repo_id="pyannote/segmentation", filename="pytorch_model.bin", use_auth_token=HF_TOKEN) snapshot_download("speechbrain/spkrec-ecapa-voxceleb")
次にpyannote/speaker-diarization
のconfig.yaml
とpyannote/segmentation
のpytorch_model.bin
について、実体を分かりやすい場所にコピーしておき、元フォルダ自体は削除します。
!cp -L {segmentation_model_path} ./assets/pytorh_model.bin !cp -L {config_path} ./assets/config.yaml !rm -rf ./assets/models--pyannote--segmentation !rm -rf ./assets/models--pyannote--speaker-diarization
本時点でファイル構成は以下のようになります。
!find ./assets # ./assets # ./assets/config.yaml # ./assets/pytorh_model.bin # ./assets/models--speechbrain--spkrec-ecapa-voxceleb # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/refs # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/refs/main # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/72c6fa7b170cbfd169df5e09326cd97febdf086a # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/fd9e3634fe68bd0a427c95e354c0c677374f62b3f434e45b78599950d860d535 # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/2d5abbd526328179f0516569cb9ff5ddd289a1fc # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/c79d72cc1197b4b32646fb55b18f4baf69a33dc1 # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/ce0fb75939a3929f13c0d2e3c848781a80b04006 # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/2e8b3b4d97ae58d7daa78954a5c7f5b8abb42934 # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/0575cb64845e6b9a10db9bcb74d5ac32b326b8dc90352671d345e2ee3d0126a2 # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/99d49dbaf2c68699660d729649d87b80ebbd9b9d # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/1978c5e7f20d5ffd14c8a932a7e85a09816f3da9 # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/a38e3061f91ba51b02b7ef4c5fd4d088659c183d # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/config.json # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/embedding_model.ckpt # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/.gitattributes # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/label_encoder.txt # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/example1.wav # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/example2.flac # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/hyperparams.yaml # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/classifier.ckpt # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/README.md # ./assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/mean_var_norm_emb.ckpt
こちらをそのままzipに固めておきます。
!zip -r assets.zip ./assets
こちらをダウンロードするなどしてどこか別の場所に置いておきます。そして一旦Google Colaboratoryを削除します。
モデル取得
使用する際は、assets.zip
をまずアップロードし、任意の場所で展開します。いまはカレントディレクトリにassets.zip
があると想定します。
こちらを例えば./tmp
に展開します。
!unzip assets.zip -d ./tmp # Archive: assets.zip # creating: ./tmp/assets/ # inflating: ./tmp/assets/config.yaml # inflating: ./tmp/assets/pytorh_model.bin # creating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/ # creating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/refs/ # extracting: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/refs/main # creating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/ # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/72c6fa7b170cbfd169df5e09326cd97febdf086a # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/fd9e3634fe68bd0a427c95e354c0c677374f62b3f434e45b78599950d860d535 # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/2d5abbd526328179f0516569cb9ff5ddd289a1fc # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/c79d72cc1197b4b32646fb55b18f4baf69a33dc1 # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/ce0fb75939a3929f13c0d2e3c848781a80b04006 # extracting: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/2e8b3b4d97ae58d7daa78954a5c7f5b8abb42934 # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/0575cb64845e6b9a10db9bcb74d5ac32b326b8dc90352671d345e2ee3d0126a2 # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/99d49dbaf2c68699660d729649d87b80ebbd9b9d # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/1978c5e7f20d5ffd14c8a932a7e85a09816f3da9 # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/blobs/a38e3061f91ba51b02b7ef4c5fd4d088659c183d # creating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/ # creating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/ # extracting: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/config.json # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/embedding_model.ckpt # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/.gitattributes # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/label_encoder.txt # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/example1.wav # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/example2.flac # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/hyperparams.yaml # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/classifier.ckpt # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/README.md # inflating: ./tmp/assets/models--speechbrain--spkrec-ecapa-voxceleb/snapshots/5c0be3875fda05e81f3c004ed8c7c06be308de1e/mean_var_norm_emb.ckpt
展開したフォルダに応じて、config.yaml
を以下で書き換えます。
import yaml with open("./tmp/assets/config.yaml", 'r') as yml: config = yaml.safe_load(yml) config["pipeline"]["params"]["segmentation"] = "./tmp/assets/pytorh_model.bin" with open("./tmp/assets/config.yaml", 'w') as f: yaml.dump(config, f)
最後にHUGGINGFACE_HUB_CACHE
を展開したフォルダに応じて書き換えます。こちらは絶対パスで指定しておきます。
import os import pathlib os.environ['HUGGINGFACE_HUB_CACHE'] = str(pathlib.Path("./tmp/assets").absolute())
こちらで準備が整いました。
話者ダイアライゼーションのテスト
準備が整ったので、話者ダイアライゼーション処理をしてみます。
今回は公式のノートブックで使用されていた音声を使います。
!wget -q http://groups.inf.ed.ac.uk/ami/AMICorpusMirror/amicorpus/ES2004a/audio/ES2004a.Mix-Headset.wav !ls -ltra ./ES2004a.Mix-Headset.wav # -rw-r--r-- 1 root root 33579394 Mar 14 2005 ./ES2004a.Mix-Headset.wav
以下でpipelineをインスタンス化します。
from pyannote.audio import Pipeline from pyannote.core import Segment, notebook, Annotation import json import polars as pl pipeline = Pipeline.from_pretrained("./tmp/assets/config.yaml")
音声ファイルを処理します。
%%time diarization = pipeline("./ES2004a.Mix-Headset.wav") # CPU times: user 49.1 s, sys: 460 ms, total: 49.6 s # Wall time: 50 s
以下を実行すると結果を確認できます。
diarization
その他、処理結果の扱いは前回の記事に譲ります。
まとめ
いかがでしたでしょうか。本記事ではダウンロード済みのモデルを使用してpyannote.audioのspeaker diarizationを行う方法を見ていきました。
これでAWS Batchなどでも動作させる目途が得られたと思います。
本記事の内容が皆様の参考になれば幸いです。